package org.jiangy.authentication.store;

import jakarta.annotation.Resource;
import jakarta.transaction.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.jiangy.authentication.DefaultGrantedAuthority;
import org.jiangy.usercenter.entity.Customer;
import org.jiangy.usercenter.entity.Staff;
import org.jiangy.usercenter.entity.User;
import org.jiangy.usercenter.entity.UserTypeEnum;
import org.jiangy.usercenter.repository.SupplierRepository;
import org.jiangy.usercenter.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Example;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.UserDetailsManager;
import org.springframework.stereotype.Service;

/**
 * <p>创建时间: 2024/8/12 </p>
 *
 * @author <a href="mailto:jiangliu0316@outlook.com" rel="nofollow">蒋勇</a>
 */
@Slf4j
@Service
public class DefaultJdbcUserDetailsManager implements UserDetailsManager {
    @Resource
    private UserRepository userRepository;
    @Resource
    private SupplierRepository supplierRepository;

    @Autowired
    @Lazy
    private PasswordEncoder passwordEncoder;

    @Transactional
    @Override
    public void createUser(UserDetails user) {
        if (user instanceof Customer customer) {
            userRepository.save(customer);
            supplierRepository.save(customer.getSupplierInfo());
        } else if (user instanceof Staff staff) {
            userRepository.save(staff);
        }
    }

    @Override
    public void updateUser(UserDetails user) {

    }

    @Override
    public void deleteUser(String username) {

    }

    @Override
    public void changePassword(String oldPassword, String newPassword) {
        // TODO: 修改密码规则
        // TODO: 获取当前登录用户
        User user = (User) SecurityContextHolder.getContext()
                .getAuthentication()
                .getPrincipal();
        if (!this.passwordEncoder.matches(oldPassword, user.getPassword())) {
            log.debug("Failed to authenticate since password does not match stored value");
            throw new BadCredentialsException("Bad credentials");
        }
        user.setPassword(this.passwordEncoder.encode(newPassword));
        userRepository.save(user);
    }

    @Override
    public boolean userExists(String username) {

        Example<User> example = Example.of(new User() {
            @Override
            public String getUsername() {
                return username;
            }
        });

        return userRepository.exists(example);
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        User user = userRepository.findByUsername(username).orElseThrow(() -> new UsernameNotFoundException(username));
        // TODO: 加载用户权限
        if (user.getType() == UserTypeEnum.CUSTOMER) {
            user.getAuthorities().add(new DefaultGrantedAuthority("ROLE_USER"));
        }
        if (user.getType() == UserTypeEnum.STAFF) {
            user.getAuthorities().add(new DefaultGrantedAuthority("ROLE_ADMIN"));
        }
//        return new UserDetailsProxy<>(user);
        return user;
    }
}
